#include <iostream>
#include <set>
#include <map>
#include <vector>
#include <functional>
using namespace std;

void test_set()
{
	//set<int> s;
	//s.insert(4);
	//s.insert(2);
	//s.insert(1);

	//set<int> s = { 1, 2, 1, 6, 3, 8, 5 }; C++11

	int arr[] = { 1, 2, 1, 6, 3, 8, 5 };
	set<int> s(arr, arr + sizeof(arr) / sizeof(arr[0]));
	//set<int, greater<int>> s(arr, arr + sizeof(arr) / sizeof(arr[0]));

	// 排序 + 去重
	set<int>::iterator it = s.begin();
	while (it != s.end())
	{
		//*it = 10; // 和前面二叉搜索树一样不能修改
		cout << *it << " ";
		++it;
	}
	cout << endl;

	for (const auto& e : s)
	{
		cout << e << " ";
	}
	cout << endl;
	cout << "size = " << s.size() << endl;

	s.erase(2);
	s.erase(30); // 直接用erase,没有删除的元素什么事都没
	for (const auto& e : s)
	{
		cout << e << " ";
	}
	cout << endl;

	set<int>::iterator pos = s.find(20); // 用find删除，要判断，不然崩溃
	if (pos != s.end())
	{
		s.erase(pos);
	}
	pos = s.find(8); // 用find删除，要判断，不然崩溃
	if (pos != s.end())
	{
		s.erase(pos);
	}

	for (const auto& e : s)
	{
		cout << e << " ";
	}
	cout << endl;
	cout << "size = " << s.size() << endl;
	cout << s.empty() << endl;
}

void test_multiset()
{
	int arr[] = { 1, 2, 1, 6, 3, 8, 5, 3, 3 };
	multiset<int> ms(arr, arr + sizeof(arr) / sizeof(arr[0]));
	for (const auto& e : ms)
	{
		cout << e << " ";
	}
	cout << endl;
	cout << ms.count(1) << endl; // set也有这个接口，是为了和multiset一致，在set中可以用来找元素在不在

	// find时，如果有多个值，返回中序的第一个
	auto pos = ms.find(3);
	while (pos != ms.end())
	{
		cout << *pos << " ";
		++pos; // ++是+到中序的下一个
	}
	cout << endl;

	ms.erase(3); // 删除所有的3
	for (const auto& e : ms)
	{
		cout << e << " ";
	}
	cout << endl;

	pos = ms.find(1); // 删除一个1
	if (pos != ms.end())
	{
		ms.erase(pos);
	}
	for (const auto& e : ms)
	{
		cout << e << " ";
	}
	cout << endl;
}

void test_map1()
{
	map<string, string> dict;
	//pair<string, string> kv1("sort", "排序");
	//dict.insert(kv1);

	dict.insert(pair<string, string>("sort", "排序")); // 等价于上面注释
	dict.insert(pair<string, string>("test", "测试"));
	dict.insert(pair<string, string>("string", "字符串"));
	typedef pair<string, string> DictKV;
	dict.insert(DictKV("string", "xxx"));
	dict.insert(make_pair("left", "左边")); // 常用这种插入
	dict["right"] = "右边"; // 更常用这种插入

	//map<string, string>::iterator it = dict.begin();
	auto it = dict.begin(); // 等价于上面注释
	while (it != dict.end())
	{
		//cout << (*it).first << (*it).second <<endl;
		cout << it->first << ":" << it->second << endl; // 等价于上面注释
		++it;
	}
	cout << endl;

	for (const auto& kv : dict)
	{
		cout << kv.first << ":" << kv.second << endl;
	}
	cout << endl;
}

void test_map2()
{
	//map<string, int> countMap;
	//for (const auto& str : arr)
	//{
	//	map<string, int>::iterator it = countMap.find(str);
	//	if (it != countMap.end())
	//	{
	//		//(*it).second++;
	//		it->second++;
	//	}
	//	else
	//	{
	//		countMap.insert(make_pair(str, 1));
	//	}
	//}

	string arr[] = { "苹果", "西瓜", "苹果", "西瓜", "苹果", "苹果", "西瓜", "苹果", "香蕉", "苹果", "香蕉" };
	map<string, int> countMap;
	for (const auto& str : arr) // 等同于上面一大段注释
	{
		// 1、str不在countMap中，插入pair(str, int()),然后在对返回次数++
		// 2、str在countMap中，返回value(次数)的引用，次数++;
		countMap[str]++;
	}

	map<string, int>::iterator it = countMap.begin();
	while (it != countMap.end())
	{
		cout << it->first << ":" << it->second << endl;
		++it;
	}
	cout << endl;
}

void test_multimap()
{
	map<string, string> dict;
	dict.insert(make_pair("sort", "排序"));
	dict["insert"];
	dict["insert"] = "插入";
	dict["left"] = "左边";
	dict["left"] = "左边";
	for (const auto& kv : dict)
	{
		cout << kv.first << ":" << kv.second << endl;
	}
	cout << dict.size() << endl;

	multimap<string, string> mdict;
	mdict.insert(make_pair("sort", "排序"));
	mdict.insert(make_pair("right", "右边"));
	mdict.insert(make_pair("right", "正确"));
	mdict.insert(make_pair("right", "右边")); // 正常插入，不管key值
	for (const auto& kv : mdict)
	{
		cout << kv.first << ":" << kv.second << endl;
	}
	cout << mdict.size() << endl;
}

void my_test()
{
	vector<int> v = { 3,2,1,6,5,4,9,8,7,0 ,2,3,4,5,6 };

	set<int> s(v.begin(), v.end());

	for (const auto& e : s)
	{
		cout << e << " ";
	}
	cout << endl << "s.size() = " << s.size() << endl;

	map<string, int> countMap;
	string arr[] = { "doiwahjdipajd" , "love", "awpdj", "wapo" ,"you", "i" , "you"
		,"i" "idj", "love"  ,"love", "ka" ,"i"  ,"i"  , "you" };

	for (const auto& str : arr)
	{
		countMap[str]++;
	}

	multimap<int, string, greater<int>> sortMap;
	for (const auto& kv : countMap)
	{
		sortMap.insert(pair<int, string>(kv.second, kv.first));
	}

	map<int, string>::iterator it = sortMap.begin();
	while (it != sortMap.end())
	{
		cout << it->second << " : " << it->first << endl;
		++it;
	}
}

int main()
{
	//test_set();
	//test_multiset();
	//test_map1();
	//test_map2();
	//test_multimap();
	my_test();

	return 0;
}